home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / internet / irc_i_dodatki / eggdrop / eggdrop11.lha / weed < prev   
Text File  |  1997-01-15  |  13KB  |  373 lines

  1. #!/usr/local/bin/tclsh
  2. #
  3. # weed out certain undesirables from an eggdrop userlist
  4. # try just typing 'tclsh weed' to find out the options
  5. #    Robey Pointer, november 1994
  6. #
  7. # <cmwagner@gate.net>:
  8. # I did a few bug fixes to the original weed script, things changed...
  9. #
  10. # when specifying other weed options they would unset the User() field and
  11. # a maxlast weed would try and weed again and cause the script to stop due
  12. # to User() being already unset  (array nonexistant)
  13. #
  14. # when loadUserFile encountered an xtra field it would try and use the $info
  15. # variable, which was supposed to be $xtra (something overlooked when the
  16. # line was cut and pasted -- I hate it when that happens)
  17. #
  18. # changed the formatting of the saved weed file to match more closely to
  19. # eggdrop 0.9tp (so this may cause incompatibilities), but when a hostmask
  20. # field exactly matched 40 characters it would save it with no spaces after it
  21. # and eggdrop would reject the user record.  I know I could have easily changed
  22. # one character, but I couldn't help myself.  <grin>
  23. #                                         5 march 96
  24. #
  25. # <robey, 23jul96>:
  26. #   upgrade for v2 userfiles
  27. #
  28. # <bruce s, 4sep96>:
  29. #   fixed xtra field from getting truncated
  30. #
  31. # <robey, 20sep96>:
  32. #   stopped it from mangling channel ban lists
  33.  
  34.  
  35. # by default, banlist and ignorelist are exempt from weeding
  36. set exempt {*ban *ignore}
  37.  
  38. # don't exempt ops, masters, or friends; or +p or +x
  39. set exemptops 0 ; set exemptmasters 0 ; set exemptfriends 0
  40. set exemptparty 0 ; set exemptfile 0
  41.  
  42. # default maximum seconds since last seen: 0 = infinite
  43. set maxlast 0
  44.  
  45. # default maximum seconds since ban used: 0 = infinite
  46. set maxban 0
  47. # default maximum seconds since ignore created: 0 = infinite
  48. set maxignore 0
  49.  
  50. # don't weed passwordless ops and/or masters -- don't weed ppl w/ no pw
  51. set weedops 0 ; set weedmasters 0 ; set weednopw 0
  52.  
  53. # don't unop/unmaster passwordless ops and/or masters
  54. set stripops 0 ; set stripmasters 0
  55.  
  56. # don't weed people just cos they've never logged on
  57. set weedlurkers 0
  58.  
  59.  
  60. # tricky way to get the current timestamp
  61. set fd [open "/tmp/egg.timer." w]
  62. close $fd
  63. set CURRENT [file atime "/tmp/egg.timer."]
  64. exec rm -f /tmp/egg.timer.
  65.  
  66. if {$argc < 1} {
  67.   puts stdout "\nUsage: weed <userfile> \[options\]"
  68.   puts stdout "  (weeds out users from an eggdrop userlist)"
  69.   puts stdout "Output goes to <userfile>.weed"
  70.   puts stdout "Possible options:"
  71.   puts stdout "  -<nick>        exempt this user from weeding"
  72.   puts stdout "  ^o  ^m  ^f     exempt ops or masters or friends"
  73.   puts stdout "  ^p  ^x         exempt party-line or file-area users"
  74.   puts stdout "  +<days>        weed: haven't been seen in N days"
  75.   puts stdout "  :n             weed: haven't EVER been seen"
  76.   puts stdout "  :o  :m         weed: ops or masters with no password set"
  77.   puts stdout "  :a             weed: anyone with no pasword set"
  78.   puts stdout "  o   m          unop/unmaster: ops or masters with no pass."
  79.   puts stdout "  b<days>        weed: bans not used in N days"
  80.   puts stdout "  i<days>        weed: ignores created over N days ago"
  81.   puts stdout ""
  82.   exit
  83. }
  84. puts stdout "\nWEED  5mar96, robey\n"
  85.  
  86. # process arguments
  87. set filename [lindex $argv 0]
  88. for {set i 1} {$i < $argc} {incr i} {
  89.   # each arg
  90.   set carg [lindex $argv $i]
  91.   if {$carg == ":n"} { 
  92.     set weedlurkers 1 
  93.   } elseif {$carg == ":o"} {
  94.     set weedops 1 ; set stripops 0 ; set weednopw 0
  95.   } elseif {$carg == ":m"} { 
  96.     set weedmasters 1 ; set stripmasters 0 ; set weednopw 0
  97.   } elseif {$carg == ":a"} {
  98.     set weednopw 1 ; set weedops 0 ; set weedmasters 0
  99.     set stripops 0 ; set stripmasters 0
  100.   } elseif {$carg == "o"} {
  101.     set stripops 1 ; set weedops 0 ; set weednopw 0
  102.   } elseif {$carg == "m"} {
  103.     set stripmasters 1 ; set weedmasters 0 ; set weednopw 0
  104.   } elseif {$carg == "^m"} {
  105.     set exemptmasters 1
  106.   } elseif {$carg == "^o"} {
  107.     set exemptops 1
  108.   } elseif {$carg == "^f"} {
  109.     set exemptfriends 1
  110.   } elseif {$carg == "^p"} {
  111.     set exemptparty 1
  112.   } elseif {$carg == "^x"} {
  113.     set exemptfile 1
  114.   } elseif {[string index $carg 0] == "-"} {
  115.     lappend exempt [string range $carg 1 end]
  116.   } elseif {[string index $carg 0] == "+"} {
  117.     set maxlast [expr 60*60*24* [string range $carg 1 end]]
  118.   } elseif {[string index $carg 0] == "b"} {
  119.     set maxban [expr 60*60*24* [string range $carg 1 end]]
  120.   } elseif {[string index $carg 0] == "i"} {
  121.     set maxignore [expr 60*60*24* [string range $carg 1 end]]
  122.   } else {
  123.     puts stderr "UNKNOWN OPTION: '$carg'\n"
  124.     exit
  125.   }
  126. }
  127.  
  128. if {(!$weedlurkers) && (!$weedops) && (!$weedmasters) && (!$weednopw) &&
  129.     (!$stripops) && (!$stripmasters) && ($maxlast == 0) &&
  130.     ($maxban == 0) && ($maxignore == 0)} {
  131.   puts stderr "PROBLEM: You didn't specify anything to weed out.\n"
  132.   exit
  133. }
  134. set weeding {}
  135. if {$weedlurkers} { set weeding "$weeding lurkers" }
  136. if {$weedops} { set weeding "$weeding pwdless-ops" }
  137. if {$weedmasters} { set weeding "$weeding pwdless-masters" }
  138. if {$weednopw} { set weeding "$weeding pwdless-users" }
  139. if {$maxlast > 0} {
  140.   set weeding "$weeding >[expr $maxlast /(60*60*24)]-days"
  141. }
  142. if {$maxban > 0} {
  143.   set weeding "$weeding bans>[expr $maxban /(60*60*24)]-days"
  144. }
  145. if {$maxignore > 0} {
  146.   set weeding "$weeding ign>[expr $maxignore /(60*60*24)]-days"
  147. }
  148. if {$weeding != {}} { puts stdout "Weeding:$weeding" }
  149. set strip {}
  150. if {$stripops} { set strip "$strip pwdless-ops" }
  151. if {$stripmasters} { set strip "$strip pwdless-masters" }
  152. if {$strip != {}} { puts stdout "Stripping:$strip" }
  153. set exempting {}
  154. if {$exemptops} { set exempting "$exempting (ops)" }
  155. if {$exemptmasters} { set exempting "$exempting (masters)" }
  156. if {$exemptfriends} { set exempting "$exempting (friends)" }
  157. if {$exemptparty} { set exempting "$exempting (party-line)" }
  158. if {$exemptfile} { set exempting "$exempting (file-area)" }
  159. if {[llength $exempt]>2} { set exempting "$exempting [lrange $exempt 2 end]" }
  160. if {$exempting != {}} { puts stdout "Exempt:$exempting" }
  161.  
  162. puts stdout "\nReading $filename ..."
  163.  
  164. # User($handle)        { "password" "attr" "timestamp" "dccdir" "email"
  165. #                        "comment" "infoline" "xtra" }
  166. # Hostmask($handle)    { "*!*@*" "*!*@*" ... }
  167. #
  168. # -hostmask(s) *dccdir +email =comment :infoline
  169.  
  170. # returns 1 if loaded okay
  171. proc loadUserFile {fname} {
  172.   global User Hostmask
  173.   set oldhandle {}
  174.   if {[catch {set fd [open $fname r]}] != 0} { return 0 }
  175.   set line [string trim [gets $fd]]
  176.   if {[string range $line 1 2] != "2v"} {
  177.     puts stderr "Unknown userfile version!  (not v2)\n"
  178.     exit
  179.   }
  180.   while {![eof $fd]} {
  181.     set line [string trim [gets $fd]]
  182.     if {([string index $line 0] != "#") && ([string length $line] > 0)} {
  183.       # not a comment, and something on the line!
  184.       scan $line "%s" handle
  185.       if {$handle == "-"} {
  186.         # hostmask list (shudder!)
  187.         set hmList [split [string range $line 2 end] ,]
  188.         # trim the items in this list (remove whitespace)
  189.         for {set i 0} {$i < [llength $hmList]} {incr i} {
  190.           lappend Hostmask($oldhandle) [string trim [lindex $hmList $i]]
  191.         }
  192.       } elseif {$handle == "*"} {
  193.         # dccdir
  194.         set dccdir [string trim [string range $line 2 end]]
  195.         set User($oldhandle) [lreplace $User($oldhandle) 3 3 $dccdir]
  196.       } elseif {$handle == "+"} {
  197.         # email
  198.         set email [string trim [string range $line 2 end]]
  199.         set User($oldhandle) [lreplace $User($oldhandle) 4 4 $email]
  200.       } elseif {$handle == "="} {
  201.         # comment
  202.         set comment [string trim [string range $line 2 end]]
  203.         set User($oldhandle) [lreplace $User($oldhandle) 5 5 $comment]
  204.       } elseif {$handle == ":"} {
  205.         # user info line
  206.         set info [string trim [string range $line 2 end]]
  207.         set User($oldhandle) [lreplace $User($oldhandle) 6 6 $info]
  208.       } elseif {$handle == "."} {
  209.         # xtra field
  210.         set xtra [lindex $User($oldhandle) 7]
  211.         lappend xtra [string trim [string range $line 2 end]]
  212.         set User($oldhandle) [lreplace $User($oldhandle) 7 7 $xtra]
  213.       } else {
  214.         # begin of new user
  215.         scan $line "%s %s %s %s" handle pass attr ts
  216.         set User($handle) [list $pass $attr $ts {} {} {} {} {}]
  217.         set Hostmask($handle) {}
  218.         set oldhandle $handle
  219.       }
  220.     }
  221.   }
  222.   return 1
  223. }
  224.  
  225. # returns 1 if saved okay
  226. proc saveUserFile fname {
  227.   global User Hostmask
  228.   if {[catch {set fd [open $fname w]}] != 0} { return 0 }
  229.   puts $fd "#2v: weed!  now go away."
  230.   foreach i [array names User] {
  231.     set hmask "none"
  232.     set loop 0
  233.     set pass [lindex $User($i) 0]
  234.     set attr [lindex $User($i) 1]
  235.     set ts [lindex $User($i) 2]
  236.     puts $fd [format "%-9s %-20s %-24s %s" $i $pass $attr $ts]
  237.     for {} {$loop < [llength $Hostmask($i)]} {incr loop} {
  238.       puts $fd "- [lindex $Hostmask($i) $loop]"
  239.     }
  240.     if {[lindex $User($i) 3] != {}} { puts $fd "* [lindex $User($i) 3]" }
  241.     if {[lindex $User($i) 4] != {}} { puts $fd "+ [lindex $User($i) 4]" }
  242.     if {[lindex $User($i) 5] != {}} { puts $fd "= [lindex $User($i) 5]" }
  243.     if {[lindex $User($i) 6] != {}} { puts $fd ": [lindex $User($i) 6]" }
  244.     if {[lindex $User($i) 7] != {}} { 
  245.       foreach xline [lindex $User($i) 7] {
  246.         puts $fd ". $xline"
  247.       }
  248. #      puts $fd ". [lindex $User($i) 7]" 
  249.     }
  250.   }
  251.   close $fd
  252.   return 1
  253. }
  254.  
  255. if {![loadUserFile $filename]} {
  256.   puts stderr "* Couldn't load userfile!\n"
  257.   exit
  258. }
  259. puts stdout "Loaded.  Weeding..."
  260. puts stdout "(pwd = no pass, -o/-m = removed op/master, lrk = never seen, exp = expired)\n"
  261.  
  262. #
  263. # the main part
  264. #
  265. set total 0
  266. set weeded 0
  267. foreach i [array names User] {
  268.   incr total
  269.   set attr [lindex $User($i) 1]
  270.   if {([lsearch -exact $exempt $i] == -1) &&
  271.       ([string range $i 0 1] != "::") &&
  272.       (([string first o $attr] == -1) || (!$exemptops)) &&
  273.       (([string first m $attr] == -1) || (!$exemptmasters)) &&
  274.       (([string first f $attr] == -1) || (!$exemptfriends)) &&
  275.       (([string first p $attr] == -1) || (!$exemptparty)) &&
  276.       (([string first x $attr] == -1) || (!$exemptfile))} {
  277.     # not exempt from weeding
  278.     set pass [lindex $User($i) 0]
  279.     set ts [lindex $User($i) 2]
  280.     if {([string compare $pass "-"] == 0) &&
  281.         ([string first b $attr] == -1)} {
  282.       # no password, bad boy/girl!
  283.       if {$weednopw == 1} {
  284.         unset User($i) ; incr weeded
  285.         puts -nonewline stdout "[format "pwd: %-10s     " $i]"
  286.       } elseif {([string first o $attr] != -1) && ($weedops == 1)} {
  287.         unset User($i) ; incr weeded
  288.         puts -nonewline stdout "[format "pwd: %-10s     " $i]"
  289.       } elseif {([string first m $attr] != -1) && ($weedmasters == 1)} {
  290.         unset User($i) ; incr weeded
  291.         puts -nonewline stdout "[format "pwd: %-10s     " $i]"
  292.       } 
  293.       if {([string first o $attr] != -1) && ($stripops == 1)} {
  294.         set nattr {}
  295.         for {set x 0} {$x < [string length $attr]} {incr x} {
  296.           if {[string index $attr $x] != "o"} {
  297.             set nattr [format "%s%s" $nattr [string index $attr $x]]
  298.           }
  299.         }
  300.         if {$nattr == {}} { set nattr "-" }
  301.         set User($i) [lreplace $User($i) 1 1 $nattr]
  302.         puts -nonewline stdout "[format " -o: %-10s     " $i]"
  303.       }
  304.       if {([string first m $attr] != -1) && ($stripmasters == 1)} {
  305.         set nattr {}
  306.         for {set x 0} {$x < [string length $attr]} {incr x} {
  307.           if {[string index $attr $x] != "m"} {
  308.             set nattr [format "%s%s" $nattr [string index $attr $x]]
  309.           }
  310.         }
  311.         if {$nattr == {}} { set nattr "-" }
  312.         set User($i) [lreplace $User($i) 1 1 $nattr]
  313.         puts -nonewline stdout "[format " -m: %-10s     " $i]"
  314.       }
  315.     }
  316.     if {($ts == 0) && ($weedlurkers==1) && ([string first b $attr]==-1) &&
  317.     [info exists User($i)]} {
  318.       unset User($i) ; incr weeded
  319.       puts -nonewline stdout "[format "lrk: %-10s     " $i]"
  320.     } 
  321.     if {($ts > 0) && ($maxlast > 0) && ($CURRENT-$ts > $maxlast &&
  322.     [info exists User($i)])} {
  323.       unset User($i) ; incr weeded
  324.       puts -nonewline stdout "[format "exp: %-10s     " $i]"
  325.     }
  326.   }
  327.   flush stdout
  328. }
  329. puts stdout "\n"
  330.  
  331. # now check bans/ignores
  332. foreach i [array names User] {
  333.   if {([string range $i 0 1] == "::") || ($i == "*ban")} {
  334.     # channel-specific bans!
  335.     for {set j 0} {$j < [llength $Hostmask($i)]} {incr j} {
  336.       set ban [split [lindex $Hostmask($i) $j] :]
  337.       # make sure it's a modern ban:
  338.       if {[string range [lindex $ban 2] 0 0] == "+"} {
  339.         set lastused [lindex $ban 3]
  340.         if {($maxban > 0) && ($CURRENT-$lastused > $maxban)} {
  341.           if {$i == "*ban"} {
  342.             puts stdout "Expired ban: [lindex $ban 0]"
  343.           } {
  344.             puts stdout "Expired ban on [string range $i 2 end]: [lindex $ban 0]"
  345.           }
  346.           set Hostmask($i) [lreplace $Hostmask($i) $j $j]
  347.           incr j -1
  348.         }
  349.       }
  350.     }
  351.   }
  352.   if {$i == "*ignore"} {
  353.     for {set j 0} {$j < [llength $Hostmask($i)]} {incr j} {
  354.       set ign [split [lindex $Hostmask($i) $j] :]
  355.       set lastused [lindex $ign 3]
  356.       if {($maxignore > 0) && ($CURRENT-$lastused > $maxignore)} {
  357.         puts stdout "Expired ignore: [lindex $ign 0]"
  358.         set Hostmask($i) [lreplace $Hostmask($i) $j $j]
  359.         incr j -1
  360.       }
  361.     }
  362.   }
  363. }
  364.  
  365. puts stdout "\nFinished scan."
  366. puts stdout "Original total ($total), new total ([expr $total-$weeded]), zapped ($weeded)"
  367.  
  368. if {![saveUserFile $filename.weed]} {
  369.   puts stderr "* Couldn't save new userfile!\n"
  370.   exit
  371. }
  372. puts stdout "Wrote $filename.weed"
  373.